
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
#include <modbus.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "shmem.h"
// 数据类型定义
typedef enum
{
    TYPE_BOOL = 1,  // 布尔类型
    TYPE_INT = 2,   // 整数类型
    TYPE_FLOAT = 3, // 浮点类型
} DataType;

// STM32设备点表项
typedef struct
{
    uint16_t key;   // 点表键值
    char name[32];  // 点表名称
    DataType type;  // 数据类型
    uint8_t status; // 状态标志(0=无效,1=有效)
    union
    {
        int int_value;
        float float_value;
        int bool_value;
    } value;
} STM32Item;

// Modbus设备点表项
typedef struct
{
    uint16_t key;   // 点表键值
    char name[32];  // 点表名称
    uint16_t addr;  // Modbus地址
    DataType type;  // 数据类型
    uint8_t status; // 状态标志(0=无效,1=有效)
    union
    {
        int int_value;
        float float_value;
        int bool_value;
    } value;
} ModbusItem;

// 完整配置结构体
typedef struct
{
    int stm32_count;            // STM32点表项数量
    STM32Item stm32_items[100]; // 与写入程序保持一致

    int modbus_count;             // Modbus点表项数量
    ModbusItem modbus_items[100]; // 与写入程序保持一致

    // 其他配置信息
    char version[10]; // 配置版本
    struct
    {
        int type;   // 报告类型
        int period; // 报告周期
    } report;
    struct
    {
        char addr[20]; // MQTT服务器地址
        int port;      // MQTT服务器端口
    } mqtt_server;
    struct
    {
        char addr[20];
        int port;
    } mb_dev;
    struct
    {
        char addr[20]; // Modbus应用地址
        int port;

    } mb_app;
} ConfigData;

#define SHARED_MEM_NAME "point_table_shm"
#define SEM_NAME "/point_table_shm_sem"
struct shm_param shm;
sem_t *shm_sem;
// 将共享内存地址转换为ConfigData结构体指针
ConfigData *config = NULL;
modbus_t *ctx;
void *modbusRead(void *arg)
{
    // if (shm_sem == SEM_FAILED)
    // {
    //     perror("Failed to open semaphore");
    // }

    // 计算共享内存所需大小
    const size_t SHARED_MEM_SIZE = sizeof(ConfigData);
    printf("ConfigData size: %zu bytes\n", SHARED_MEM_SIZE);

    // 初始化共享内存（这里只是获取信息，不会重新创建共享内存）
    if (shm_init(&shm, SHARED_MEM_NAME, SHARED_MEM_SIZE, 0) != 0)
    {
        fprintf(stderr, "Failed to initialize shared memory\n");
        sem_close(shm_sem);
    }

    // 获取共享内存地址
    void *shm_addr = shm_getaddr(&shm);
    if (shm_addr == NULL)
    {
        fprintf(stderr, "Failed to attach shared memory\n");
        sem_close(shm_sem);
    }
    config = (ConfigData *)shm_addr;
    // 读寄存器操作
    while (1)
    {
        ModbusItem *ModbusItem;

        int nb = 3;
        char buf[128];
        uint16_t dest[32] = {};
        if (modbus_read_registers(ctx, 0, nb, dest) < 0)
        {
            printf("read_registers err\n");
            return NULL;
        }
        sprintf(buf, "心率：%d,光照:%d,y:血氧%d\n", dest[0], dest[1], dest[2]);
        printf("buf:%s", buf);

        for (int i = 0; i < 3; i++)
        {
            config->modbus_items[i].key = i;
            config->modbus_items[i].addr = i;
            config->modbus_items[i].type = TYPE_INT;
            config->modbus_items[i].status = 1;
            config->modbus_items[i].value.int_value = dest[i];
             printf("111\n");
            if (shm_write(&shm, &config, sizeof(ConfigData)) != 0)
            {
                fprintf(stderr, "Failed to write to shared memory\n");
                // free(json_data);
                // cJSON_Delete(root);
            }
             printf("111\n");
        }
        sleep(4);
    }
    // shmdt(p);
    // shmctl(shmid, IPC_RMID, NULL);
}
int main()
{
    // 打开信号量
    //shm_sem = sem_open(SEM_NAME, 0);
    // 加锁读取共享内存
    //sem_wait(shm_sem);
    printf("111\n");
    // // 打印读取到的部分信息
    // printf("version: %s\n", config->version);
    // printf("report type: %d\n", config->report.type);
    // printf("report period: %d\n", config->report.period);
    // printf("mqtt_server addr: %s\n", config->mqtt_server.addr);
    // printf("mqtt_server port: %d\n", config->mqtt_server.port);
    // printf("mb_dev addr: %s\n", config->mb_dev.addr);
    // printf("mb_dev port: %d\n", config->mb_dev.port);
    // printf("mb_app addr: %s\n", config->mb_app.addr);
    // printf("mb_app port: %d\n", config->mb_app.port);

    // printf("STM32 Items:\n");
    // for (int i = 0; i < config->stm32_count && i < 100; i++)
    // {
    //     printf("  key: %d, name: %s, type: %d, status: %d\n",
    //            config->stm32_items[i].key,
    //            config->stm32_items[i].name,
    //            config->stm32_items[i].type,
    //            config->stm32_items[i].status);

    //     // 根据type打印对应的值
    //     switch (config->stm32_items[i].type)
    //     {
    //     case TYPE_BOOL:
    //         printf("    value: %s\n", config->stm32_items[i].value.bool_value ? "true" : "false");
    //         break;
    //     case TYPE_INT:
    //         printf("    value: %d\n", config->stm32_items[i].value.int_value);
    //         break;
    //     case TYPE_FLOAT:
    //         printf("    value: %.2f\n", config->stm32_items[i].value.float_value);
    //         break;
    //     default:
    //         printf("    value: [invalid type %d]\n", config->stm32_items[i].type);
    //         break;
    //     }
    // }

    // printf("Modbus Items:\n");
    // for (int i = 0; i < config->modbus_count && i < 100; i++)
    // {
    //     printf("  key: %d, name: %s, addr: %d, type: %d, status: %d\n",
    //            config->modbus_items[i].key,
    //            config->modbus_items[i].name,
    //            config->modbus_items[i].addr,
    //            config->modbus_items[i].type,
    //            config->modbus_items[i].status);

    //     // 根据type打印对应的值
    //     switch (config->modbus_items[i].type)
    //     {
    //     case TYPE_BOOL:
    //         printf("    value: %s\n", config->modbus_items[i].value.bool_value ? "true" : "false");
    //         break;
    //     case TYPE_INT:
    //         printf("    value: %d\n", config->modbus_items[i].value.int_value);
    //         break;
    //     case TYPE_FLOAT:
    //         printf("    value: %.2f\n", config->modbus_items[i].value.float_value);
    //         break;
    //     default:
    //         printf("    value: [invalid type %d]\n", config->modbus_items[i].type);
    //         break;
    //     }
    // }

    // 解锁
    //sem_post(shm_sem);
    char ip[32] = "192.168.51.102";
    int port = 502;
    ctx = modbus_new_tcp(ip, port);
    if (ctx == NULL)
    {
        printf("modbus_new_tco err\n");
        return -1;
    }
    // 设置从机IDmodbus_set_slave
    if (modbus_set_slave(ctx, 01) < 0)
    {
        printf("set_slave err\n");
        return -1;
    }
    // 和从机进行连接modbus_connect
    if (modbus_connect(ctx) < 0)
    {
        printf("connect err\n");
        return -1;
    }
    pthread_t tidr;
    if (pthread_create(&tidr, NULL, modbusRead, NULL))
    {
        printf("create pthread readerr");
        return -1;
    }
    pthread_detach(tidr);
    while (1)
        ;

    // 关闭套接字modbus_close
    modbus_close(ctx);
    // 释放实力modus_free
    modbus_free(ctx);
    /*
        // 解除共享内存映射
        if (shm_del(&shm) != 0)
        {
            fprintf(stderr, "Failed to detach shared memory\n");
            sem_close(shm_sem);
            return 1;
        }
    */
    // 关闭信号量
    sem_close(shm_sem);

    return 0;
}